package com.ruoyi.user.controller;

import com.ruoyi.common.core.constant.HttpStatus;
import com.ruoyi.common.core.exception.CaptchaException;
import com.ruoyi.common.core.web.controller.BaseController;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.redis.service.RedisService;
import com.ruoyi.user.domain.UserDetail;
import com.ruoyi.user.domain.UserOrder;
import com.ruoyi.user.service.ip.IpLanguageMatcher;
import com.ruoyi.user.model.LoginInfo;
import com.ruoyi.user.service.*;
import com.ruoyi.user.model.RegisterType;
import com.ruoyi.user.model.ShortMessageParams;
import com.ruoyi.user.utils.Servlets;
import com.ruoyi.user.utils.UserSessionUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

/**
 * @author: houyong
 * @date: 2025年11月14日 15:11
 */
@Tag(name = "网站前端用户接口", description = "网站前端用户接口")
@RestController
@RequestMapping("/user/website")
public class UserWebSiteController extends BaseController {

    @Autowired
    private SsmService ssmService;

    @Autowired
    private UserDetailService userDetailService;
    @Autowired
    private IpLanguageMatcher ipLanguageMatcher;
    @Autowired
    private RedisService redisService;
    @Autowired
    private TranslateService translateService;
    @Autowired
    private IUserOrderService userOrderService;
    @Autowired
    private ValidateCodeService validateCodeService;

    @Operation(summary = "用户获取图片验证码")
    @GetMapping("/code")
    public AjaxResult getCode() {
        try {
            return validateCodeService.createCaptcha();
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error("获取验证码失败");
        }
    }

    @Deprecated
    @Operation(summary = "发送手机短信")
    @PostMapping("sms/mobile")
    public AjaxResult mobileMessage(@RequestBody ShortMessageParams params, HttpServletRequest request) {
        try {
            validateCodeService.checkCaptcha(params.getCaptcha() ,params.getCaptchaToken());
            String messageId = ssmService.sendMobileMessage(params.receiver);
            if (StringUtils.isNotEmpty(messageId)) {
                return AjaxResult.success(messageId);
            }
            return AjaxResult.error("发送手机号验证码失败");
        } catch (CaptchaException e) {
            return AjaxResult.error(e.getMessage());
        }

    }

    @Operation(summary = "发送邮件短信")
    @PostMapping("sms/email")
    public AjaxResult emailMessage(@RequestBody ShortMessageParams params, HttpServletRequest request) {
        try {
            validateCodeService.checkCaptcha(params.getCaptcha() ,params.getCaptchaToken());
            String ip = Servlets.getRemoteAddr(request, 1);
            params.setUsage((short) 1);
            String language = params.getLanguage();
            if (StringUtils.isBlank(language)) {
                language = ipLanguageMatcher.getLanguageByIp(ip);
            }
            params.setLanguage(language);
            String messageId = ssmService.sendMail(new String[]{params.receiver}, language);
            if (StringUtils.isNotEmpty(messageId)) {
                return AjaxResult.success(messageId);
            }
            return AjaxResult.error("发送邮箱验证码失败");
        } catch (CaptchaException e) {
            return AjaxResult.error(e.getMessage());
        }
    }

    @Operation(summary = "用户注册接口", description = "支持手机号和邮箱注册")
    @PostMapping("/register")
    public AjaxResult register(@Parameter(description = "注册类型 1:手机号 2:邮箱") @RequestParam Integer type,
                               @Parameter(description = "手机号") @RequestParam(required = false) String phone,
                               @Parameter(description = "邮箱") @RequestParam(required = false) String email,
                               @Parameter(description = "密码") @RequestParam String password,
                               @Parameter(description = "验证码") @RequestParam String code,
                               @Parameter(description = "验证码ID") @RequestParam String messageId,
                               HttpServletRequest request) {
        try {
            // 参数校验
            if (type == null || (type != RegisterType.EMAIL.getCode() && type != RegisterType.PHONE.getCode())) {
                return AjaxResult.error("注册类型错误");
            }
            String receiver = null;
            if (type == RegisterType.PHONE.getCode()) {
                // 手机号注册
                if (StringUtils.isBlank(phone)) {
                    return AjaxResult.error("手机号不能为空");
                }
                receiver = phone;
            } else if (type == RegisterType.EMAIL.getCode()) {
                // 邮箱注册
                if (StringUtils.isBlank(email)) {
                    return AjaxResult.error("邮箱不能为空");
                }
                receiver = email;
            }
            if (StringUtils.isBlank(password)) {
                return AjaxResult.error("密码不能为空");
            }
            if (StringUtils.isBlank(code)) {
                return AjaxResult.error("验证码不能为空");
            }
            if (StringUtils.isBlank(messageId)) {
                return AjaxResult.error("验证码ID不能为空");
            }
            // 验证码校验
            boolean codeValid = ssmService.tryCode(messageId, receiver, code);
            if (!codeValid) {
                return AjaxResult.error("验证码错误或已过期");
            }
            AjaxResult registerResult = userDetailService.register(phone, email, password, type);
            if (registerResult.isSuccess()) {
                redisService.deleteObject(messageId);
            }
            return registerResult;
        } catch (Exception e) {
            return AjaxResult.error("注册失败: " + e.getMessage());
        }
    }

    @Operation(summary = "用户登录接口", description = "支持手机号和邮箱登录")
    @RequestMapping(method = RequestMethod.POST, value = "/auth/login")
    public AjaxResult login(@RequestBody LoginInfo info) {
        try {
            validateCodeService.checkCaptcha(info.getCaptcha(), info.getCaptchaToken());
            return userDetailService.login(info);
        } catch (CaptchaException e) {
            return AjaxResult.error(e.getMessage());
        }


    }

    @Operation(summary = "用户退出登录接口", description = "用户退出登录")
    @PostMapping("/auth/logout")
    public AjaxResult logout(HttpServletRequest request) {
        UserDetail userDetail = UserSessionUtils.getUserDetail(request, redisService);
        if (userDetail == null) {
            return AjaxResult.success();
        }
        return userDetailService.logoutBySessionId(UserSessionUtils.getUserSessionId(request));
    }

    @Operation(summary = "用户信息接口", description = "通过session信息查询用户信息")
    @GetMapping("/info/by/sessionId")
    public AjaxResult getUserDetailBySessionId(HttpServletRequest request) {
        UserDetail userDetail = UserSessionUtils.getUserDetail(request, redisService);
        if (userDetail == null) {
            return AjaxResult.error(HttpStatus.UNAUTHORIZED, "用户未登录");
        }
        return AjaxResult.success(userDetail);
    }

    @Operation(summary = "用户修改密码接口", description = "用户修改自己的密码")
    @PostMapping("/user/password/update")
    public AjaxResult updatePassword(@RequestParam String oldPassword,
                                     @RequestParam String newPassword, HttpServletRequest request) {
        try {
            UserDetail userDetail = UserSessionUtils.getUserDetail(request, redisService);
            if (userDetail == null) {
                return AjaxResult.error(HttpStatus.UNAUTHORIZED, "用户未登录");
            }
            return userDetailService.updatePassword(userDetail.getUid(), oldPassword, newPassword);
        } catch (Exception e) {
            return AjaxResult.error("密码修改失败: " + e.getMessage());
        }
    }

    @Deprecated
    @Operation(summary = "用户修改手机号接口", description = "用户修改绑定的手机号")
    @PostMapping("/user/phone/update")
    public AjaxResult updatePhone(@RequestParam String newPhone,
                                  @RequestParam String code,
                                  @RequestParam String messageId, HttpServletRequest request) {
        try {
            UserDetail userDetail = UserSessionUtils.getUserDetail(request, redisService);
            if (userDetail == null) {
                return AjaxResult.error(HttpStatus.UNAUTHORIZED, "用户未登录");
            }
            // 验证码校验
            boolean codeValid = ssmService.tryCode(messageId, newPhone, code);
            if (!codeValid) {
                return AjaxResult.error("验证码错误或已过期");
            }
            return userDetailService.updatePhone(userDetail.getUid(), newPhone);
        } catch (Exception e) {
            return AjaxResult.error("手机号修改失败: " + e.getMessage());
        }
    }

    @Operation(summary = "用户修改邮箱接口", description = "用户修改绑定的邮箱")
    @PostMapping("/user/email/update")
    public AjaxResult updateEmail(
            @RequestParam String newEmail,
            @RequestParam String code,
            @RequestParam String messageId, HttpServletRequest request) {
        try {
            UserDetail userDetail = UserSessionUtils.getUserDetail(request, redisService);
            if (userDetail == null) {
                return AjaxResult.error(HttpStatus.UNAUTHORIZED, "用户未登录");
            }
            // 验证码校验
            boolean codeValid = ssmService.tryCode(messageId, newEmail, code);
            if (!codeValid) {
                return AjaxResult.error("验证码错误或已过期");
            }
            return userDetailService.updateEmail(userDetail.getUid(), newEmail);
        } catch (Exception e) {
            return AjaxResult.error("邮箱修改失败: " + e.getMessage());
        }
    }

    @Operation(summary = "用户修改用户信息接口", description = "用户修改头像、昵称等信息")
    @PostMapping("/user/info/update")
    public AjaxResult updateUserInfo(@RequestBody UserDetail userDetail, HttpServletRequest request) {
        try {
            UserDetail userDetailInfo = UserSessionUtils.getUserDetail(request, redisService);
            if (userDetailInfo == null) {
                return AjaxResult.error(HttpStatus.UNAUTHORIZED, "用户未登录");
            }
            userDetail.setUid(userDetailInfo.getUid());
            return userDetailService.updateUserInfo(userDetail);
        } catch (Exception e) {
            return AjaxResult.error("用户信息修改失败: " + e.getMessage());
        }
    }

    @Operation(summary = "获取用户语言接口", description = "根据用户IP获取用户语言")
    @GetMapping("/user/language")
    public AjaxResult getUserLanguage(@RequestParam(required = false) String ip, HttpServletRequest request) {
        try {
            String remoteAddrIp = Servlets.getRemoteAddr(request, 1);
            if (ip == null) {
                ip = remoteAddrIp;
            }
            String language = ipLanguageMatcher.getLanguageByIp(ip);
            return AjaxResult.success("获取用户语言成功", language);
        } catch (Exception e) {
            return AjaxResult.error("获取用户语言失败: " + e.getMessage());
        }
    }

    @Operation(summary = "翻译接口")
    @Parameters({
            @Parameter(name = "formatType", description = "格式类型(text：文本 html:网页)", required = false),
            @Parameter(name = "scene", description = "场景：general：通用场景", required = false),
            @Parameter(name = "sourceLanguage", description = "源语言：默认zh", required = false),
            @Parameter(name = "targetLanguage", description = "目标语言 【语言列表中的value】", required = true),
            @Parameter(name = "text", description = "待翻译文本", required = true)
    })
    @GetMapping("/user/translate")
    public AjaxResult translate(@RequestParam(required = false, defaultValue = "text") String formatType,
                                @RequestParam(required = false, defaultValue = "general") String scene,
                                @RequestParam(required = false, defaultValue = "zh") String sourceLanguage,
                                @RequestParam String targetLanguage,
                                @RequestParam String text, HttpServletRequest request) {
        try {
            String translatedText = translateService.translate(formatType,
                    scene, sourceLanguage, targetLanguage, text);
            return AjaxResult.success("翻译成功", translatedText);
        } catch (Exception e) {
            return AjaxResult.error("翻译失败: " + e.getMessage());
        }
    }

    /**
     * 新增用户订单
     */
    @Operation(summary = "创建用户订单接口", description = "创建用户订单")
    @Parameters({
            @Parameter(name = "goodsId", description = "商品ID", required = true)
    })
    @PostMapping("/order/create")
    public AjaxResult createOrder(@RequestParam Integer goodsId, HttpServletRequest request) {
        UserDetail userDetailInfo = UserSessionUtils.getUserDetail(request, redisService);
        if (userDetailInfo == null) {
            return AjaxResult.error(HttpStatus.UNAUTHORIZED, "用户未登录");
        }
        return userOrderService.insertUserOrder(goodsId, userDetailInfo.getUid());
    }

    @Operation(summary = "用户订单列表接口", description = "用户订单列表")
    @Parameters({
            @Parameter(name = "pageNum", description = "页码", required = false),
            @Parameter(name = "pageSize", description = "每页数量", required = false)
    })
    @GetMapping("order/list")
    public AjaxResult searchUserOrderList(@RequestParam(required = false, defaultValue = "1") Integer pageNum,
                                          @RequestParam(required = false, defaultValue = "10") Integer pageSize,
                                          HttpServletRequest request) {
        UserDetail userDetailInfo = UserSessionUtils.getUserDetail(request, redisService);
        if (userDetailInfo == null) {
            return AjaxResult.error(HttpStatus.UNAUTHORIZED, "用户未登录");
        }
        startPage();
        UserOrder userOrder = new UserOrder();
        userOrder.setUid(userDetailInfo.getUid());
        List<UserOrder> list = userOrderService.selectUserOrderList(userOrder);
        return AjaxResult.success(getDataTable(list));
    }
}
